import Fastify from 'fastify'
import cors from '@fastify/cors'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'
import { readFileSync } from 'fs'
import { initDB } from '../../shared/db/index.js'
import * as db from '../../shared/db/queries.js'
import * as adDb from '../../shared/db/ad-queries.js'
import * as favoriteDb from '../../shared/db/favorite-queries.js'
import * as historyDb from '../../shared/db/history-queries.js'
import * as recommendationDb from '../../shared/db/recommendation-queries.js'
import * as userDb from '../../shared/db/user-queries.js'
import crypto from 'crypto'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

// 读取环境变量
const env = {}
try {
  const envFile = readFileSync(join(__dirname, '../.env'), 'utf-8')
  envFile.split('\n').forEach(line => {
    const [key, ...values] = line.split('=')
    if (key && values.length) {
      env[key.trim()] = values.join('=').trim()
    }
  })
} catch (e) {
  console.log('未找到 .env 文件，使用默认配置')
}

const PORT = parseInt(env.PORT || process.env.PORT || '3000')

// 初始化数据库
initDB()

// 创建 Fastify 实例
const fastify = Fastify({
  logger: true
})

// 注册 CORS
fastify.register(cors, {
  origin: true
})

// 响应格式插件
fastify.addHook('onSend', async (request, reply, payload) => {
  if (typeof payload === 'object') {
    return JSON.stringify({
      code: reply.statusCode === 200 ? 200 : 400,
      message: reply.statusCode === 200 ? 'success' : 'error',
      data: payload
    })
  }
  return payload
})

// 健康检查
fastify.get('/health', async (request, reply) => {
  return { status: 'ok', timestamp: new Date().toISOString() }
})

// 获取图片列表
fastify.get('/api/images/list', async (request, reply) => {
  try {
    const { page = 1, pageSize = 20, category, status = 1 } = request.query
    const offset = (parseInt(page) - 1) * parseInt(pageSize)
    const limit = parseInt(pageSize)
    
    // 判断是否需要推荐：只有在获取全部图片（category为空或"all"）且用户已登录时才推荐
    const shouldRecommend = (!category || category === 'all') && page === 1
    
    if (shouldRecommend) {
      // 尝试获取用户ID（可能未登录）
      try {
        const userId = await getUserId(request)
        
        if (userId) {
          // 获取用户推荐图片
          const recommendedImages = recommendationDb.getUserRecommendedImages(userId, limit)
          
          if (recommendedImages.length > 0) {
            // 获取总数（用于分页）
            const totalResult = db.getImages({
              offset: 0,
              limit: 1,
              category,
              status: parseInt(status)
            })
            
            return {
              list: recommendedImages,
              total: totalResult.total,
              page: parseInt(page),
              pageSize: parseInt(pageSize),
              recommended: true // 标记这是推荐结果
            }
          }
        }
      } catch (err) {
        // 用户未登录或获取用户ID失败，使用默认排序
        // 继续执行下面的默认逻辑
      }
    }
    
    // 默认逻辑：按时间排序
    const result = db.getImages({
      offset,
      limit,
      category,
      status: parseInt(status)
    })
    
    return {
      list: result.list,
      total: result.total,
      page: parseInt(page),
      pageSize: parseInt(pageSize),
      recommended: false
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 获取图片详情
fastify.get('/api/images/:id', async (request, reply) => {
  try {
    const { id } = request.params
    const image = db.getImageById(parseInt(id))

    if (!image) {
      reply.code(404)
      return { error: '图片不存在' }
    }

    // 增加浏览数
    db.incrementImageViews(parseInt(id))

    return image
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 获取分类列表
fastify.get('/api/images/category', async (request, reply) => {
  try {
    const { status = 1 } = request.query
    const categories = db.getCategoriesWithImageCount({ status: parseInt(status) })
    
    return categories.map(cat => ({
      id: cat.id,
      name: cat.name,
      slug: cat.slug,
      count: cat.count || 0
    }))
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 搜索图片
fastify.get('/api/images/search', async (request, reply) => {
  try {
    const { keyword, page = 1, pageSize = 20 } = request.query
    
    if (!keyword) {
      reply.code(400)
      return { error: '关键词不能为空' }
    }

    const result = db.searchImages({
      keyword,
      offset: (parseInt(page) - 1) * parseInt(pageSize),
      limit: parseInt(pageSize)
    })

    return {
      list: result.list,
      total: result.total,
      page: parseInt(page),
      pageSize: parseInt(pageSize)
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// ============ 广告配置接口 ============

// 获取广告配置
fastify.get('/api/config/ads', async (request, reply) => {
  try {
    const { platform = 'mp-weixin' } = request.query
    
    const config = adDb.getAdConfig(platform)
    
    if (!config) {
      reply.code(404)
      return { error: '未找到广告配置' }
    }
    
    return config
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 记录广告展示
fastify.post('/api/ads/show', async (request, reply) => {
  try {
    const { type, adUnitId, platform = 'mp-weixin', timestamp } = request.body
    
    if (!type || !adUnitId) {
      reply.code(400)
      return { error: '缺少必要参数' }
    }
    
    adDb.recordAdEvent({
      platform,
      adType: type,
      adUnitId,
      eventType: 'show',
      timestamp
    })
    
    return { message: '记录成功' }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 记录广告点击
fastify.post('/api/ads/click', async (request, reply) => {
  try {
    const { type, adUnitId, platform = 'mp-weixin', timestamp } = request.body
    
    if (!type || !adUnitId) {
      reply.code(400)
      return { error: '缺少必要参数' }
    }
    
    adDb.recordAdEvent({
      platform,
      adType: type,
      adUnitId,
      eventType: 'click',
      timestamp
    })
    
    return { message: '记录成功' }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// ============ 应用配置接口 ============

// 获取应用配置
fastify.get('/api/config/app', async (request, reply) => {
  try {
    const config = adDb.getAppConfig()
    return config
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// ============ 用户登录接口 ============

// 获取用户标识（从 token 或请求头）
async function getUserId(request) {
  // 优先从 token 获取
  try {
    let token = request.headers.authorization?.replace(/^Bearer\s+/i, '').trim()
    // 去除前后引号（防止某些客户端发送带引号的 token）
    if (token) {
      token = token.replace(/^["']|["']$/g, '')
      // 简单的 token 验证（实际应该使用 JWT）
      // 这里假设 token 就是 userId（或可以解码出 userId）
      // 为了安全，可以从 token 中解析用户信息
      const userId = await verifyToken(token)
      if (userId) {
        return userId
      }
    }
  } catch (err) {
    // token 无效，继续其他方式
  }
  
  // 从请求头获取
  const userId = request.headers['x-user-id'] || 
                 request.query.userId ||
                 request.body?.userId
  
  if (userId) {
    return userId
  }
  
  // 如果没有提供，返回 null（需要登录）
  return null
}

// 验证 token（简化版，实际应该使用 JWT）
async function verifyToken(token) {
  // 这里可以从 token 中解析用户ID
  // 简化处理：假设 token 格式为 userId:timestamp:sign
  try {
    // 去除前后引号和空格（防止某些客户端发送带引号的 token）
    const cleanToken = token.trim().replace(/^["']|["']$/g, '')
    const parts = cleanToken.split(':')
    if (parts.length >= 2) {
      return parts[0] // 返回 userId
    }
  } catch (err) {
    // 解析失败
  }
  return null
}

// 生成 token
function generateToken(userId) {
  const timestamp = Date.now()
  const sign = crypto.createHash('md5').update(`${userId}:${timestamp}:secret`).digest('hex').substring(0, 8)
  return `${userId}:${timestamp}:${sign}`
}

// 获取客户端真实IP（考虑代理情况）
function getClientIp(request) {
  // 优先从 X-Forwarded-For 获取（代理转发）
  const forwardedFor = request.headers['x-forwarded-for']
  if (forwardedFor) {
    // X-Forwarded-For 可能是多个IP，取第一个
    const ips = forwardedFor.split(',').map(ip => ip.trim())
    return ips[0]
  }
  
  // 从 X-Real-IP 获取（nginx代理）
  const realIp = request.headers['x-real-ip']
  if (realIp) {
    return realIp
  }
  
  // 直接使用 request.ip
  return request.ip || request.socket.remoteAddress || 'unknown'
}

// 获取User-Agent
function getUserAgent(request) {
  return request.headers['user-agent'] || 'unknown'
}

// 微信小程序登录
fastify.post('/api/auth/weixin/login', async (request, reply) => {
  try {
    const { code } = request.body
    
    if (!code) {
      reply.code(400)
      return { error: 'code不能为空' }
    }
    
    // 这里需要调用微信API获取openid
    // 需要配置小程序的 appid 和 secret
    const WX_APPID = process.env.WX_APPID || ''
    const WX_SECRET = process.env.WX_SECRET || ''
    
    if (!WX_APPID || !WX_SECRET) {
      reply.code(500)
      return { error: '微信配置未设置' }
    }
    
    // 调用微信登录接口
    const wxUrl = `https://api.weixin.qq.com/sns/jscode2session?appid=${WX_APPID}&secret=${WX_SECRET}&js_code=${code}&grant_type=authorization_code`
    
    // 使用 Node.js 内置的 fetch（Node.js 18+）或 node-fetch
    let fetchFunc
    try {
      // 尝试使用内置 fetch
      fetchFunc = globalThis.fetch || fetch
    } catch (e) {
      // 如果没有内置 fetch，使用 node-fetch
      const nodeFetch = await import('node-fetch')
      fetchFunc = nodeFetch.default
    }
    
    const wxRes = await fetchFunc(wxUrl)
    const wxData = await wxRes.json()
    
    if (wxData.errcode) {
      reply.code(400)
      return { error: wxData.errmsg || '微信登录失败' }
    }
    
    const { openid, unionid, session_key } = wxData
    
    // 获取登录IP和User-Agent
    const clientIp = getClientIp(request)
    const userAgent = getUserAgent(request)
    
    // 创建或更新用户
    const user = userDb.upsertUser({
      userId: openid,
      type: 'weixin',
      openid: openid,
      unionid: unionid || null,
      sessionKey: session_key,
      platform: 'mp-weixin',
      lastLoginIp: clientIp,
      lastLoginUserAgent: userAgent
    })
    
    // 生成 token
    const token = generateToken(user.userId)
    
    return {
      token,
      userId: user.userId,
      userInfo: {
        userId: user.userId,
        type: user.type,
        nickname: user.nickname,
        avatar: user.avatar
      }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 游客登录（H5）
fastify.post('/api/auth/guest/login', async (request, reply) => {
  try {
    const { visitorId, platform = 'h5' } = request.body
    
    let userId = visitorId
    
    // 如果没有提供 visitorId，生成一个
    if (!userId) {
      userId = `guest_${crypto.randomBytes(8).toString('hex')}_${Date.now()}`
    } else {
      // 清理 userId，去除前后引号和空格
      userId = userId.trim().replace(/^["']+|["']+$/g, '')
      // 确保格式正确
      if (!userId.startsWith('guest_')) {
        userId = `guest_${userId}`
      }
    }
    
    // 获取登录IP和User-Agent
    const clientIp = getClientIp(request)
    const userAgent = getUserAgent(request)
    
    // 创建或更新游客用户
    const user = userDb.upsertUser({
      userId: userId,
      type: 'guest',
      platform: platform,
      lastLoginIp: clientIp,
      lastLoginUserAgent: userAgent
    })
    
    // 生成 token
    const token = generateToken(user.userId)
    
    return {
      token,
      userId: user.userId,
      userInfo: {
        userId: user.userId,
        type: user.type,
        platform: user.platform
      }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 验证 token
fastify.get('/api/auth/verify', async (request, reply) => {
  try {
    let token = request.headers.authorization?.replace(/^Bearer\s+/i, '').trim()
    
    if (!token) {
      reply.code(401)
      return { error: '未提供token' }
    }
    
    // 去除前后引号（防止某些客户端发送带引号的 token）
    token = token.replace(/^["']|["']$/g, '')
    
    const userId = await verifyToken(token)
    
    if (!userId) {
      reply.code(401)
      return { error: 'token无效' }
    }
    
    const user = userDb.getUserByUserId(userId)
    
    if (!user) {
      reply.code(401)
      return { error: '用户不存在' }
    }
    
    return {
      valid: true,
      userId: user.userId,
      userInfo: {
        userId: user.userId,
        type: user.type,
        nickname: user.nickname,
        avatar: user.avatar,
        platform: user.platform
      }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// ============ 收藏接口 ============

// 获取用户标识（需要登录）
async function getUserIdForAuth(request) {
  const userId = await getUserId(request)
  
  if (!userId) {
    throw new Error('请先登录')
  }
  
  return userId
}

// 添加收藏
fastify.post('/api/favorites', async (request, reply) => {
  try {
    const { imageId } = request.body
    const userId = await getUserIdForAuth(request)
    
    if (!imageId) {
      reply.code(400)
      return { error: '图片ID不能为空' }
    }
    
    const success = favoriteDb.addFavorite(userId, parseInt(imageId))
    
    if (success) {
      return { success: true, message: '收藏成功' }
    } else {
      return { success: false, message: '已收藏' }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 取消收藏
fastify.delete('/api/favorites/:imageId', async (request, reply) => {
  try {
    const { imageId } = request.params
    const userId = await getUserIdForAuth(request)
    
    const success = favoriteDb.removeFavorite(userId, parseInt(imageId))
    
    if (success) {
      return { success: true, message: '取消收藏成功' }
    } else {
      return { success: false, message: '未收藏' }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 检查是否已收藏
fastify.get('/api/favorites/check/:imageId', async (request, reply) => {
  try {
    const { imageId } = request.params
    const userId = await getUserIdForAuth(request)
    
    const isFav = favoriteDb.isFavorite(userId, parseInt(imageId))
    
    return { isFavorite: isFav }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 获取用户收藏列表
fastify.get('/api/favorites', async (request, reply) => {
  try {
    const { page = 1, pageSize = 20 } = request.query
    const userId = await getUserIdForAuth(request)
    
    const result = favoriteDb.getUserFavorites(userId, {
      page: parseInt(page),
      pageSize: parseInt(pageSize)
    })
    
    return {
      list: result.list,
      total: result.total,
      page: parseInt(page),
      pageSize: parseInt(pageSize)
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 批量检查收藏状态
fastify.post('/api/favorites/batch-check', async (request, reply) => {
  try {
    const { imageIds } = request.body
    const userId = await getUserIdForAuth(request)
    
    if (!Array.isArray(imageIds) || imageIds.length === 0) {
      reply.code(400)
      return { error: '图片ID列表不能为空' }
    }
    
    const favoriteSet = favoriteDb.getBatchFavoriteStatus(userId, imageIds.map(id => parseInt(id)))
    
    return {
      favorites: Array.from(favoriteSet)
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// ============ 浏览历史接口 ============

// 添加浏览历史
fastify.post('/api/history', async (request, reply) => {
  try {
    const { imageId } = request.body
    const userId = await getUserIdForAuth(request)
    
    if (!imageId) {
      reply.code(400)
      return { error: '图片ID不能为空' }
    }
    
    historyDb.addViewHistory(userId, parseInt(imageId))
    
    return { success: true, message: '浏览历史已记录' }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 删除浏览历史
fastify.delete('/api/history/:imageId', async (request, reply) => {
  try {
    const { imageId } = request.params
    const userId = await getUserIdForAuth(request)
    
    const success = historyDb.removeViewHistory(userId, parseInt(imageId))
    
    if (success) {
      return { success: true, message: '已删除浏览历史' }
    } else {
      return { success: false, message: '浏览历史不存在' }
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 清空浏览历史
fastify.delete('/api/history', async (request, reply) => {
  try {
    const userId = await getUserIdForAuth(request)
    
    historyDb.clearViewHistory(userId)
    
    return { success: true, message: '浏览历史已清空' }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 获取用户浏览历史列表
fastify.get('/api/history', async (request, reply) => {
  try {
    const { page = 1, pageSize = 20 } = request.query
    const userId = await getUserIdForAuth(request)
    
    const result = historyDb.getUserViewHistory(userId, {
      page: parseInt(page),
      pageSize: parseInt(pageSize)
    })
    
    return {
      list: result.list,
      total: result.total,
      page: parseInt(page),
      pageSize: parseInt(pageSize)
    }
  } catch (error) {
    fastify.log.error(error)
    reply.code(500)
    return { error: error.message }
  }
})

// 启动服务器
const start = async () => {
  try {
    await fastify.listen({ port: PORT, host: '0.0.0.0' })
    console.log(`🚀 API 服务已启动: http://localhost:${PORT}`)
  } catch (err) {
    fastify.log.error(err)
    process.exit(1)
  }
}

start()
